package com.anti.modular.bus.busrealestate.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.anti.commom.api.Result;
import com.anti.commom.core.utils.StringUtils;
import com.anti.core.context.login.LoginContextHolder;
import com.anti.jdbc.DBUtils;
import com.anti.jdbc.support.page.PageParam;
import com.anti.jdbc.support.page.PageResult;
import com.anti.commom.core.exception.BusinessException;
import com.anti.modular.bus.billwater.result.BillWaterDetailExcel;
import com.anti.modular.bus.busrealestate.entity.BusRealEstate;
import com.anti.modular.bus.busrealestate.enums.BusRealEstateExceptionEnum;
import com.anti.modular.bus.busrealestate.param.BusRealEstateParam;
import com.anti.modular.bus.busrealestate.result.*;
import com.anti.modular.bus.busrealestate.result.excel.DepositExcel;
import com.anti.modular.bus.busrealestate.result.excel.ExpensesExcel;
import com.anti.modular.bus.busrealestate.result.excel.FurnitureExcel;
import com.anti.modular.bus.busrealestate.result.excel.StateExcel;
import com.anti.modular.bus.busrealestate.result.tree.BusRoomTreeRes;
import com.anti.modular.bus.busrealestate.result.tree.RealEstateResult;
import com.anti.modular.bus.busrealestate.result.tree.RoomItemResult;
import com.anti.modular.bus.busrealestate.result.tree.RoomListResult;
import com.anti.modular.bus.busrealestate.service.BusRealEstateService;
import com.anti.modular.bus.busrealestatefloor.param.BusRealEstateFloorParam;
import com.anti.modular.bus.busrealestatefloor.service.BusRealEstateFloorService;
import com.anti.modular.bus.busroom.entity.BusRoom;
import com.anti.modular.bus.busroom.param.BusRoomParam;
import com.anti.modular.bus.busroom.service.BusRoomService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 房产service接口实现类
 *
 * @author anti
 * @date 2021-04-12 19:05:27
 */
@Service
public class BusRealEstateServiceImpl implements BusRealEstateService {
    @Resource
    DBUtils dbUtils;
    @Resource
    BusRealEstateFloorService busRealEstateFloorService;
    @Resource
    BusRoomService busRoomService;

    @Override
    public BusRealEstate getById(BusRealEstateParam busRealEstateParam){
        String sql="select * from bus_real_estate where id =? ";
        return dbUtils.get(sql,BusRealEstate.class,busRealEstateParam.getId());
    }

    @Override
    public PageResult page(PageParam pageParam,BusRealEstateParam busRealEstateParam) {
        StringBuilder sb=new StringBuilder("select * from bus_real_estate where 1=1 ");
        ArrayList<Object> param = CollectionUtil.newArrayList();
        if (ObjectUtil.isNotNull(busRealEstateParam)) {
        }
        return dbUtils.query(pageParam,sb.toString(),param.toArray());
    }

    @Override
    public List<BusRealEstateResult> list(BusRealEstateParam busRealEstateParam) {
        String sql="select a.*,(select count(*) from bus_room where a.id=estateid and status=0) as total,(select count(*) from bus_room where a.id=estateid and status=0 and lease=1) as rentTotal from bus_real_estate a where a.status=0 and a.category='1'";
        return dbUtils.query(sql, BusRealEstateResult.class);
    }

    @Override
    public List<BusRealEstateResult> fsslist(BusRealEstateParam busRealEstateParam) {
        String sql="select * from bus_real_estate where status=0 and category='2' ";
        return dbUtils.query(sql,BusRealEstateResult.class);
    }

    @Override
    public List<RealEstateResult> getStateList(BusRealEstateParam busRealEstateParam) {
        String sql="select * from bus_real_estate where status=0 and category=1 ";
        List<RealEstateResult> results = dbUtils.query(sql, RealEstateResult.class);
        if (null == results){
            results=new ArrayList<>();
        }
        RealEstateResult fssZf=new RealEstateResult();
        fssZf.setId(0l);
        fssZf.setName("分散式房产");
        fssZf.setCategory(2);
        results.add(fssZf);
        return results;
    }

    @Override
    public List<RealEstateResult> getAllStateList() {
        String sql="select * from bus_real_estate where status=0 ";
        return dbUtils.query(sql, RealEstateResult.class);
    }

    @Override
    public List<RoomListResult> getStateRoomList(BusRealEstateParam busRealEstateParam) {
        Long id = busRealEstateParam.getId();
        int category = busRealEstateParam.getCategory();
        String name = busRealEstateParam.getName();
        List<RoomListResult> roomListResultList;
        if (category == 1){
            String sqlFloor="select * from bus_real_estate_floor where estateid =? and status = 0 order by code asc";
            roomListResultList = dbUtils.query(sqlFloor, RoomListResult.class, id);
        }else {
            String sql="select * from bus_real_estate where status=0 and category=2 ";
            roomListResultList = dbUtils.query(sql, RoomListResult.class);
        }
        if (category == 1){
            List<Long> ids=new ArrayList<>();
            roomListResultList.forEach(item->{
                ids.add(item.getId());
            });
            List<BusRoomTreeRes> busRooms = busRoomService.getBusRoomTreeResFloorIds(ids);
            roomListResultList.forEach(ite->{
                Long floorid;
                RoomItemResult itemResult;
                for (int i = 0; i < busRooms.size(); i++) {
                    floorid = busRooms.get(i).getFloorid();
                    if (ite.getId()==floorid){
                        itemResult=new RoomItemResult();
                        itemResult.setId(busRooms.get(i).getId());
                        itemResult.setName(busRooms.get(i).getCode());
                        itemResult.setZkname(busRooms.get(i).getName());
                        if(busRealEstateParam.getDisableType()==1){
                            itemResult.setDisabled(busRooms.get(i).getLease() == 1);
                        }else {
                            itemResult.setDisabled(busRooms.get(i).getLease() == 1||busRooms.get(i).getReservation() > 0);
                        }
                        itemResult.setRoomStrName(name+"-"+busRooms.get(i).getCode());
                        ite.getList().add(itemResult);
                    }
                }

            });
        }else {
            List<BusRoomTreeRes> busRooms = busRoomService.getBusRoomTreeResByStateId();
            roomListResultList.forEach(ite->{
                Long stateid;
                RoomItemResult itemResult;
                for (int i = 0; i < busRooms.size(); i++) {
                    stateid = busRooms.get(i).getEstateid();
                    if (ite.getId()==stateid){
                        itemResult=new RoomItemResult();
                        itemResult.setId(busRooms.get(i).getId());
                        itemResult.setName(busRooms.get(i).getCode());
                        itemResult.setZkname(busRooms.get(i).getName());
                        if(busRealEstateParam.getDisableType()==1){
                            itemResult.setDisabled(busRooms.get(i).getLease() == 1);
                        }else {
                            itemResult.setDisabled(busRooms.get(i).getLease() == 1||busRooms.get(i).getReservation() > 0);
                        }
                        itemResult.setRoomStrName(ite.getName()+"-"+busRooms.get(i).getCode());
                        ite.getList().add(itemResult);
                    }
                }

            });
        }
        return roomListResultList;
    }

    @Override
    public List<BusRoom> getStateRoomListByStateId(Long id) {
        List<BusRoom> roomByStateId = busRoomService.getRoomByStateId(id);
        return roomByStateId;
    }

    @Override
    public void add(BusRealEstateParam busRealEstateParam) {
        checkParam(busRealEstateParam,false);
        BusRealEstate busRealEstate = new BusRealEstate();
        BeanUtil.copyProperties(busRealEstateParam, busRealEstate);
        busRealEstate.setCreateTime(new Date());
        busRealEstate.setCreateUser(LoginContextHolder.me().getSysLoginUserId());
        busRealEstate.setStatus(0);
        //集中式
        if (busRealEstate.getCategory().intValue()==1){
            String key = dbUtils.insertKey(busRealEstate).toString();
            long aLong = Long.parseLong(key);
            Integer floors = busRealEstate.getFloors();
            Integer rooms = busRealEstate.getRooms();
            //保存楼层
            for (int a=0;a<floors;a++){
                int code=a+1;
                String name=code+"楼";
                BusRealEstateFloorParam floorParam=new BusRealEstateFloorParam();
                floorParam.setCode(code);
                floorParam.setEstateid(aLong);
                floorParam.setName(name);
                busRealEstateFloorService.add(floorParam);
                //保存房间
                for (int b=0;b<rooms;b++){
                    int code2=b+1;
                    String roomcode=code+"0"+code2;
                    String sql="select id from bus_real_estate_floor where status = 0 and estateid=? and code =?";
                    Long floorid = dbUtils.getLongValue(sql, floorParam.getEstateid(), floorParam.getCode());
                    BusRoomParam busRoomParam=new BusRoomParam();
                    BigDecimal bigDecimal = new BigDecimal("0");
                    busRoomParam.setFloorid(floorid);
                    busRoomParam.setFloor(name);
                    busRoomParam.setCode(roomcode);
                    busRoomParam.setArea("0.00");
                    busRoomParam.setDeposit( bigDecimal);
                    busRoomParam.setElevator(busRealEstate.getElevator());
                    busRoomParam.setEstateid(aLong);
                    busRoomParam.setHouseType(busRealEstateParam.getHouseType());
                    busRoomParam.setHydropower(0);
                    busRoomParam.setReceiptfu(1);
                    busRoomParam.setReceiptya(1);
                    busRoomParam.setReceiptyj(2);
                    busRoomParam.setRent(bigDecimal);
                    busRoomParam.setRoomType(0);
                    busRoomService.add(busRoomParam);
                }
            }
        }else {
            //分散式
            dbUtils.insert(busRealEstate);
        }
    }


    public Result delete(BusRealEstateParam busRealEstateParam) {
        // 判斷房間是否有出租
        int count=busRoomService.getRentRoomNumByFzId(busRealEstateParam.getId());
        if (count>0){
            return Result.fail(0,"該房產有在租租約，請先退租");
        }
        //删除楼层
        busRealEstateFloorService.deleteByFcId(busRealEstateParam.getId());
        //删除房间
        busRoomService.deleteRoomByStateId(busRealEstateParam.getId());
        BusRealEstate busRealEstate = this.queryBusRealEstate(busRealEstateParam);
        busRealEstate.setUpdateTime(new Date());
        busRealEstate.setUpdateUser(LoginContextHolder.me().getSysLoginUserId());
        busRealEstate.setStatus(2);
        dbUtils.update(busRealEstate);
        return Result.success("刪除成功");
    }

    public void edit(BusRealEstateParam busRealEstateParam) {
        checkParam(busRealEstateParam,true);
        BusRealEstate busRealEstate = this.queryBusRealEstate(busRealEstateParam);
        BeanUtil.copyProperties(busRealEstateParam, busRealEstate);
        busRealEstate.setUpdateTime(new Date());
        busRealEstate.setUpdateUser(LoginContextHolder.me().getSysLoginUserId());
        dbUtils.update(busRealEstate);
    }

    @Override
    public BusRealEstate detail(BusRealEstateParam busRealEstateParam) {
        return this.queryBusRealEstate(busRealEstateParam);
    }

    @Override
    public Result detailByType(BusRealEstateParam busRealEstateParam) {
        if (busRealEstateParam.getCategory().intValue()==1){
            return this.queryBusRealEstateJzs(busRealEstateParam);
        }else {
            return this.queryBusRealEstateFss(busRealEstateParam);
        }
    }

    public Result queryBusRealEstateJzs(BusRealEstateParam busRealEstateParam){
        String sql="select * from bus_real_estate where id =? and status=0 and category='1'";
        BusRealEstateJzsResult estateJzsResult = dbUtils.getFirst(sql, BusRealEstateJzsResult.class, busRealEstateParam.getId());
        if (StringUtils.isBlank(estateJzsResult.getPrincipal())){
            estateJzsResult.setPrincipal("未設置");
        }
        if (StringUtils.isBlank(estateJzsResult.getPhone())){
            estateJzsResult.setPhone("未設置");
        }
        if (StringUtils.isBlank(estateJzsResult.getRoompre())){
            estateJzsResult.setRoompre("");
        }
        if (StringUtils.isBlank(estateJzsResult.getRoomsuf())){
            estateJzsResult.setRoomsuf("");
        }
        int roomCount = busRoomService.getRoomCount(estateJzsResult.getId(), "1");
        int roomRentCount = busRoomService.getRoomRentCount(estateJzsResult.getId(), "1");
        List<RoomType> roomTypeByStateId = busRoomService.getRoomTypeByStateId(estateJzsResult.getId(), "1");
        estateJzsResult.setRoomTypeList(roomTypeByStateId);
        if (roomCount==0){
            estateJzsResult.setXzl("100.00%");
        }else {
            DecimalFormat df = new DecimalFormat("0.00");//格式化小数
            float num=100-(float)roomRentCount/(float)roomCount;
            String s=df.format(num);//返回一个String类型的两位小数`
            estateJzsResult.setXzl(s+"%");
        }
        RoomRentDesResult allRentDes = busRoomService.getAllRentDes(estateJzsResult.getId(), "1");
        estateJzsResult.setZzj(allRentDes.getAllrent());
        estateJzsResult.setZyj(allRentDes.getAlldeposit());
        String sqlFloor="select * from bus_real_estate_floor where estateid =? and status = 0 order by code asc";
        List<BusFloor> busFloors = dbUtils.query(sqlFloor, BusFloor.class, estateJzsResult.getId());
        List<Long> ids=new ArrayList<>();
        ids.add(estateJzsResult.getId());
        if (ids.size()>0){
            List<BusRoomResult> busRooms = busRoomService.getByIds(ids,busRealEstateParam.getSearchType(),busRealEstateParam.getSearchValue());
            if (busRooms.size()>0){
                busFloors.forEach(item->{
                    Iterator<BusRoomResult> iterator = busRooms.iterator();
                    while (iterator.hasNext()){
                        BusRoomResult next = iterator.next();
                        if (next.getFloorid().longValue()==item.getId().longValue()){
                            next.setCode(next.getCode());
                            initRoomFlag(next);
                            item.getRoom().add(next);
                        }
                    }
                });
            }
        }
        //查询房间
        estateJzsResult.setFloorData(busFloors);
        return Result.data(estateJzsResult);
    }

    private void initRoomFlag(BusRoomResult next) {
        List<RoomFlag> flags=new ArrayList<>();
        if(next.getLease()==1){//是否正在出租 （ 1 是 0 否）
            RoomFlag lase=new RoomFlag();
            lase.setColor("green");
            lase.setType(2);
            lase.setName("已租");
            flags.add(lase);
        }else if (next.getReservation()>0){
            RoomFlag lase=new RoomFlag();
            lase.setColor("yellow");
            lase.setType(2);
            lase.setName("預定");
            flags.add(lase);
        }else if(next.getLease()==0){//是否正在出租 （ 1 是 0 否）
            RoomFlag lase=new RoomFlag();
            lase.setColor("#aeb0bc");
            lase.setType(2);
            lase.setName("閑置");
            flags.add(lase);
        }
        next.setFlags(flags);
    }

    Result queryBusRealEstateFss(BusRealEstateParam busRealEstateParam){
        BusRealEstateFssResult realEstateFssResult=new BusRealEstateFssResult();
        realEstateFssResult.setId(0l);
        realEstateFssResult.setName("分散式房產");
        realEstateFssResult.setCategory("2");
        int roomCount = busRoomService.getRoomCount(0l, "2");
        int roomRentCount = busRoomService.getRoomRentCount(0l, "2");
        if (roomCount==0){
            realEstateFssResult.setXzl("100.00%");
        }else {
            DecimalFormat df = new DecimalFormat("0.00");//格式化小数
            float num=100-(float)roomRentCount/(float)roomCount;
            String s=df.format(num);//返回一个String类型的两位小数
            realEstateFssResult.setXzl(s+"%");
        }
        RoomRentDesResult allRentDes = busRoomService.getAllRentDes(null, "2");
        realEstateFssResult.setZzj(allRentDes.getAllrent());
        realEstateFssResult.setZyj(allRentDes.getAlldeposit());
        List<RoomType> roomTypeByStateId = busRoomService.getRoomTypeByStateId(null, "2");
        realEstateFssResult.setRoomTypeList(roomTypeByStateId);
        String sql="select * from bus_real_estate where category =? and status=0";
        List<BusRealEstateFss> realEstateFsses = dbUtils.query(sql, BusRealEstateFss.class, "2");
        realEstateFssResult.setFloorData(realEstateFsses);
        List<Long> ids=new ArrayList<>();
        realEstateFsses.forEach(item->{
            ids.add(item.getId());
        });
        if (ids.size()>0){
            List<BusRoomResult> busRooms = busRoomService.getByIds(ids,busRealEstateParam.getSearchType(),busRealEstateParam.getSearchValue());
            if (busRooms.size()>0){
                realEstateFsses.forEach(item->{
                    if (StringUtils.isBlank(item.getPrincipal())){
                        item.setPrincipal("未設置");
                    }
                    if (StringUtils.isBlank(item.getPhone())){
                        item.setPhone("未設置");
                    }
                    Iterator<BusRoomResult> iterator = busRooms.iterator();
                    while (iterator.hasNext()){
                        BusRoomResult next = iterator.next();
                        if (next.getEstateid()==item.getId()){
                            initRoomFlag(next);
                            item.getRoom().add(next);
                        }
                    }
                });
            }
        }
        return Result.data(realEstateFssResult);
    }
    /**
     * 获取房产
     *
     * @author anti
     * @date 2021-04-12 19:05:27
     */
    private BusRealEstate queryBusRealEstate(BusRealEstateParam busRealEstateParam) {
        BusRealEstate busRealEstate = this.getById(busRealEstateParam);
        if (ObjectUtil.isNull(busRealEstate)) {
            throw new BusinessException(BusRealEstateExceptionEnum.NOT_EXIST);
        }
        return busRealEstate;
    }

    private void checkParam(BusRealEstateParam busRealEstateParam, boolean b) {
        Long id = busRealEstateParam.getId();
        String name = busRealEstateParam.getName();
        //构建带name查询条件
        StringBuilder nameSb=new StringBuilder("select count(*) from bus_real_estate where status =0 and name =?");
        ArrayList<Object> nameParams = CollectionUtil.newArrayList();
        nameParams.add(name);
        //如果排除自己，则增加查询条件主键id不等于本条id
        if (b) {
            nameSb.append(" and id <> ?");
            nameParams.add(id);
        }
        //查询重复记录的数量
        int countByName = dbUtils.getIntValue(nameSb.toString(),nameParams.toArray());
        //如果存在重复的记录，抛出异常，直接返回前端
        if (countByName >= 1) {
            throw new BusinessException(0,"該房產已存在");
        }
    }

    @Override
    public List<StateExcel> getExportData() {
        String stateSql="select a.*,(SELECT value from sys_dict_data where type_id= 1358470065111253000 and code =a.house_type) house_type_name,b.id as room_id," +
                " b.code,b.room_type_name,b.area,b.receiptcycle,b.rent,b.deposit,b.lease " +
                " from bus_real_estate a LEFT JOIN bus_room b on a.id=b.estateid where a.status =0 and b.status=0";
        List<StateExcel> query = dbUtils.query(stateSql, StateExcel.class);
        ArrayList<Long> ids = CollectionUtil.newArrayList();
        query.forEach(item-> {
            ids.add(item.getRoomId());
        });
        if (query.size()>0){
            List<Long> myList = ids.stream().distinct().collect(Collectors.toList());
            String desSql="select * from bus_room_deposit where status = 0 and roomid in (:ids)";
            HashMap<String, Object> param = CollectionUtil.newHashMap();
            param.put("ids",myList);
            List<DepositExcel> depositExcels = dbUtils.query(desSql, DepositExcel.class, param);
            String expensesSql="select * from bus_room_expenses where status = 0 and roomid in (:ids)";
            List<ExpensesExcel> expensesExcels = dbUtils.query(expensesSql, ExpensesExcel.class, param);
            String furnitureSql="select * from bus_room_furniture where status = 0 and roomid in (:ids)";
            List<FurnitureExcel> furnitureExcels = dbUtils.query(furnitureSql, FurnitureExcel.class, param);
            for (int i = 0; i < query.size(); i++) {
                StateExcel stateExcel = query.get(i);
                List<DepositExcel> ctyList = depositExcels.stream().filter(item -> item.getRoomid() == stateExcel.getRoomId()).collect(Collectors.toList());
                stateExcel.setDepositExcels(ctyList);
                List<ExpensesExcel> collect = expensesExcels.stream().filter(item -> item.getRoomid() == stateExcel.getRoomId()).collect(Collectors.toList());
                stateExcel.setExpensesExcels(collect);
                List<FurnitureExcel> furnitureExcelList = furnitureExcels.stream().filter(item -> item.getRoomid() == stateExcel.getRoomId()).collect(Collectors.toList());
                stateExcel.setFurnitureExcels(furnitureExcelList);
            }
        }
        return query;
    }
}
